package com.hh.workorder.repository;

import com.hh.workorder.entity.RepairWorkOrder;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Predicate;
import jakarta.persistence.criteria.Root;
import org.springframework.data.jpa.domain.Specification;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

public class RepairWorkOrderSpecification implements Specification<RepairWorkOrder> {

    private final String id_like;
    private final String title_like;
    private final String status;
    private final String device_like;
    private final String assignee;
    private final String startDate;
    private final String endDate;

    public RepairWorkOrderSpecification(String id_like, String title_like, String status, String device_like, String assignee, String startDate, String endDate) {
        this.id_like = id_like;
        this.title_like = title_like;
        this.status = status;
        this.device_like = device_like;
        this.assignee = assignee;
        this.startDate = startDate;
        this.endDate = endDate;
    }

    @Override
    public Predicate toPredicate(Root<RepairWorkOrder> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
        List<Predicate> predicates = new ArrayList<>();

        if (id_like != null && !id_like.isEmpty()) {
            predicates.add(criteriaBuilder.like(
                    criteriaBuilder.lower(root.get("orderNum").as(String.class)),
                    "%" + id_like.toLowerCase() + "%"
            ));
        }

        if (title_like != null && !title_like.isEmpty()) {
            predicates.add(criteriaBuilder.like(
                    criteriaBuilder.lower(root.get("orderTitle").as(String.class)),
                    "%" + title_like.toLowerCase() + "%"
            ));
        }

        if (status != null && !status.isEmpty()) {
            predicates.add(criteriaBuilder.equal(
                    root.get("orderStatus").as(String.class),
                    status
            ));
        }

        if (device_like != null && !device_like.isEmpty()) {
            predicates.add(criteriaBuilder.like(
                    criteriaBuilder.lower(root.get("deviceType").as(String.class)),
                    "%" + device_like.toLowerCase() + "%"
            ));
        }

        if (assignee != null && !assignee.isEmpty()) {
            predicates.add(criteriaBuilder.like(
                    criteriaBuilder.lower(root.get("orderLeader").as(String.class)),
                    "%" + assignee.toLowerCase() + "%"
            ));
        }

        if (startDate != null && !startDate.isEmpty()) {
            DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE;
            LocalDate localStartDate = LocalDate.parse(startDate, formatter);
            LocalDateTime startDateTime = localStartDate.atStartOfDay();
            predicates.add(criteriaBuilder.greaterThanOrEqualTo(
                    root.get("createTime").as(LocalDateTime.class),
                    startDateTime
            ));
        }

        if (endDate != null && !endDate.isEmpty()) {
            DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE;
            LocalDate localEndDate = LocalDate.parse(endDate, formatter);
            LocalDateTime endDateTime = localEndDate.plusDays(1).atStartOfDay();
            predicates.add(criteriaBuilder.lessThan(
                    root.get("createTime").as(LocalDateTime.class),
                    endDateTime
            ));
        }

        return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
    }
}